{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>movie_id</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>47</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:32:07</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>293</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:31:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>296</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:32:47</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>653</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2004-09-10 03:08:11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>1080</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:42:55</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id  movie_id  rating            timestamp\n",
       "0        1        47     3.5  2005-04-02 23:32:07\n",
       "1        1       293     4.0  2005-04-02 23:31:43\n",
       "2        1       296     4.0  2005-04-02 23:32:47\n",
       "3        1       653     3.0  2004-09-10 03:08:11\n",
       "4        1      1080     3.5  2005-04-02 23:42:55"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_rating_training=pd.read_csv('./data/rating_training.csv')\n",
    "df_rating_training.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "##将user_id变成user_index,movie_id变成movie_index\n",
    "def df_id_to_index(df,obj_id_name:str,obj_index_name:str=None):\n",
    "    print(\"obj_id_name==\",obj_id_name)\n",
    "    print(\"obj_index_name\",obj_index_name)\n",
    "    obj_id_to_index_dict={}\n",
    "    obj_index_to_id_dict={}\n",
    "    \n",
    "    ids=df[obj_id_name].unique().tolist()\n",
    "    \n",
    "    for index,_id in enumerate(ids):\n",
    "        obj_id_to_index_dict[_id] =index\n",
    "        obj_index_to_id_dict[index] =_id\n",
    "    \n",
    "    df[obj_id_name] =df[obj_id_name].apply(\n",
    "        lambda obj_id : obj_id_to_index_dict[obj_id]\n",
    "    )\n",
    "    \n",
    "    if obj_index_name:\n",
    "        column_names =df.columns.tolist()\n",
    "        for index,column_name in enumerate(column_names):\n",
    "            if column_name == obj_id_name:\n",
    "                column_names[index] = obj_index_name\n",
    "        df.columns=column_names\n",
    "        df[obj_index_name] = df[obj_index_name].astype(int)\n",
    "    return obj_id_to_index_dict,obj_index_to_id_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "obj_id_name== user_id\n",
      "obj_index_name user_index\n"
     ]
    }
   ],
   "source": [
    "user_id_to_index_dict,user_index_to_id_dict = df_id_to_index(df_rating_training,'user_id','user_index')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_index</th>\n",
       "      <th>movie_id</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>47</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:32:07</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>293</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:31:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>296</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:32:47</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>653</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2004-09-10 03:08:11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>1080</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:42:55</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_index  movie_id  rating            timestamp\n",
       "0           0        47     3.5  2005-04-02 23:32:07\n",
       "1           0       293     4.0  2005-04-02 23:31:43\n",
       "2           0       296     4.0  2005-04-02 23:32:47\n",
       "3           0       653     3.0  2004-09-10 03:08:11\n",
       "4           0      1080     3.5  2005-04-02 23:42:55"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_rating_training.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "obj_id_name== movie_id\n",
      "obj_index_name movie_index\n"
     ]
    }
   ],
   "source": [
    "movie_id_to_index_dict,movie_index_to_id_dict = df_id_to_index(df_rating_training,'movie_id','movie_index')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_index</th>\n",
       "      <th>movie_index</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:32:07</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:31:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:32:47</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2004-09-10 03:08:11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:42:55</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_index  movie_index  rating            timestamp\n",
       "0           0            0     3.5  2005-04-02 23:32:07\n",
       "1           0            1     4.0  2005-04-02 23:31:43\n",
       "2           0            2     4.0  2005-04-02 23:32:47\n",
       "3           0            3     3.0  2004-09-10 03:08:11\n",
       "4           0            4     3.5  2005-04-02 23:42:55"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_rating_training.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3380487 entries, 0 to 3380486\n",
      "Data columns (total 4 columns):\n",
      "user_index     int32\n",
      "movie_index    int32\n",
      "rating         float64\n",
      "timestamp      object\n",
      "dtypes: float64(1), int32(2), object(1)\n",
      "memory usage: 77.4+ MB\n"
     ]
    }
   ],
   "source": [
    "df_rating_training.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 將时间转换成时间戳\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1112456575"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a='2005-04-02 23:42:55'\n",
    "int(time.mktime(time.strptime(a,\"%Y-%m-%d %H:%M:%S\")) )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_index</th>\n",
       "      <th>movie_index</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112455927</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1112455903</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1112455967</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1094756891</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1112456575</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_index  movie_index  rating   timestamp\n",
       "0           0            0     3.5  1112455927\n",
       "1           0            1     4.0  1112455903\n",
       "2           0            2     4.0  1112455967\n",
       "3           0            3     3.0  1094756891\n",
       "4           0            4     3.5  1112456575"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_rating_training['timestamp'] = df_rating_training['timestamp'].apply(\n",
    "    lambda time_str:\n",
    "    int(time.mktime(time.strptime(time_str,\"%Y-%m-%d %H:%M:%S\")) )\n",
    ")\n",
    "\n",
    "df_rating_training['timestamp']=df_rating_training['timestamp'].astype(int)\n",
    "\n",
    "df_rating_training.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3380487 entries, 0 to 3380486\n",
      "Data columns (total 4 columns):\n",
      "user_index     int32\n",
      "movie_index    int32\n",
      "rating         float64\n",
      "timestamp      int32\n",
      "dtypes: float64(1), int32(3)\n",
      "memory usage: 64.5 MB\n"
     ]
    }
   ],
   "source": [
    "df_rating_training.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 用户和商品的打分矩阵，用户和商品时间矩阵，用户活跃度向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "52188\n",
      "7994\n"
     ]
    }
   ],
   "source": [
    "user_quantity = len(df_rating_training['user_index'].unique())\n",
    "movie_quantity = len(df_rating_training['movie_index'].unique())\n",
    "print(user_quantity)\n",
    "print(movie_quantity)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "##定义3个矩阵\n",
    "#用户对电影的打分矩阵\n",
    "user_movie_rating_array = np.zeros(shape=(user_quantity,movie_quantity))\n",
    "# #用户对电影时间矩阵\n",
    "user_movie_time_array = np.zeros(shape=(user_quantity,movie_quantity))\n",
    "# #用户活跃度向量\n",
    "user_popular_v=np.zeros(shape=user_quantity)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0...100...200...300...400...500...600...700...800...900...1000...1100...1200...1300...1400...1500...1600...1700...1800...1900...2000...2100...2200...2300...2400...2500...2600...2700...2800...2900...3000...3100...3200...3300...3400...3500...3600...3700...3800...3900...4000...4100...4200...4300...4400...4500...4600...4700...4800...4900...5000...5100...5200...5300...5400...5500...5600...5700...5800...5900...6000...6100...6200...6300...6400...6500...6600...6700...6800...6900...7000...7100...7200...7300...7400...7500...7600...7700...7800...7900...8000...8100...8200...8300...8400...8500...8600...8700...8800...8900...9000...9100...9200...9300...9400...9500...9600...9700...9800...9900...10000...10100...10200...10300...10400...10500...10600...10700...10800...10900...11000...11100...11200...11300...11400...11500...11600...11700...11800...11900...12000...12100...12200...12300...12400...12500...12600...12700...12800...12900...13000...13100...13200...13300...13400...13500...13600...13700...13800...13900...14000...14100...14200...14300...14400...14500...14600...14700...14800...14900...15000...15100...15200...15300...15400...15500...15600...15700...15800...15900...16000...16100...16200...16300...16400...16500...16600...16700...16800...16900...17000...17100...17200...17300...17400...17500...17600...17700...17800...17900...18000...18100...18200...18300...18400...18500...18600...18700...18800...18900...19000...19100...19200...19300...19400...19500...19600...19700...19800...19900...20000...20100...20200...20300...20400...20500...20600...20700...20800...20900...21000...21100...21200...21300...21400...21500...21600...21700...21800...21900...22000...22100...22200...22300...22400...22500...22600...22700...22800...22900...23000...23100...23200...23300...23400...23500...23600...23700...23800...23900...24000...24100...24200...24300...24400...24500...24600...24700...24800...24900...25000...25100...25200...25300...25400...25500...25600...25700...25800...25900...26000...26100...26200...26300...26400...26500...26600...26700...26800...26900...27000...27100...27200...27300...27400...27500...27600...27700...27800...27900...28000...28100...28200...28300...28400...28500...28600...28700...28800...28900...29000...29100...29200...29300...29400...29500...29600...29700...29800...29900...30000...30100...30200...30300...30400...30500...30600...30700...30800...30900...31000...31100...31200...31300...31400...31500...31600...31700...31800...31900...32000...32100...32200...32300...32400...32500...32600...32700...32800...32900...33000...33100...33200...33300...33400...33500...33600...33700...33800...33900...34000...34100...34200...34300...34400...34500...34600...34700...34800...34900...35000...35100...35200...35300...35400...35500...35600...35700...35800...35900...36000...36100...36200...36300...36400...36500...36600...36700...36800...36900...37000...37100...37200...37300...37400...37500...37600...37700...37800...37900...38000...38100...38200...38300...38400...38500...38600...38700...38800...38900...39000...39100...39200...39300...39400...39500...39600...39700...39800...39900...40000...40100...40200...40300...40400...40500...40600...40700...40800...40900...41000...41100...41200...41300...41400...41500...41600...41700...41800...41900...42000...42100...42200...42300...42400...42500...42600...42700...42800...42900...43000...43100...43200...43300...43400...43500...43600...43700...43800...43900...44000...44100...44200...44300...44400...44500...44600...44700...44800...44900...45000...45100...45200...45300...45400...45500...45600...45700...45800...45900...46000...46100...46200...46300...46400...46500...46600...46700...46800...46900...47000...47100...47200...47300...47400...47500...47600...47700...47800...47900...48000...48100...48200...48300...48400...48500...48600...48700...48800...48900...49000...49100...49200...49300...49400...49500...49600...49700...49800...49900...50000...50100...50200...50300...50400...50500...50600...50700...50800...50900...51000...51100...51200...51300...51400...51500...51600...51700...51800...51900...52000...52100..."
     ]
    }
   ],
   "source": [
    "for user_index,groupby_userindex in df_rating_training.groupby('user_index'):\n",
    "    movies_rating=groupby_userindex.groupby('movie_index')['rating'].mean()\n",
    "    movies_time=groupby_userindex.groupby('movie_index')['rating'].mean()\n",
    "    for movie_index in movies_rating.index:\n",
    "        user_movie_rating_array[user_index][movie_index] =movies_rating[movie_index]\n",
    "    for movie_index in movies_time.index:\n",
    "        user_movie_time_array[user_index][movie_index] = movies_time[movie_index]\n",
    "    user_popular_v[user_index] =len(movies_rating)\n",
    "    \n",
    "    if user_index % 100 ==0 :print(user_index,end='...')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3.5, 4. , 4. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 0. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 0. , ..., 0. , 0. , 0. ],\n",
       "       ...,\n",
       "       [3.5, 0. , 0. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 4. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 4.5, ..., 0. , 0. , 0. ]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_movie_rating_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3.5, 4. , 4. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 0. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 0. , ..., 0. , 0. , 0. ],\n",
       "       ...,\n",
       "       [3.5, 0. , 0. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 4. , ..., 0. , 0. , 0. ],\n",
       "       [0. , 0. , 4.5, ..., 0. , 0. , 0. ]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_movie_time_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([43., 43., 51., ..., 42., 30., 93.])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_popular_v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.264, 0.264, 0.253, ..., 0.266, 0.291, 0.22 ])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#计算时间惩罚因子\n",
    "user_popular_punish_v=np.around(1/np.log(1+user_popular_v),3) \n",
    "user_popular_punish_v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构建电影与电影之间的相似度矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "movie_sim_array =np.zeros(shape=(movie_quantity,movie_quantity))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0...100...200...300...400...500...600...700...800...900...1000...1100...1200...1300...1400...1500...1600...1700...1800...1900...2000...2100...2200...2300...2400...2500...2600...2700...2800...2900...3000...3100...3200...3300...3400...3500...3600...3700...3800...3900...4000...4100...4200...4300...4400...4500...4600...4700...4800...4900...5000...5100...5200...5300...5400...5500...5600...5700...5800...5900...6000...6100...6200...6300...6400...6500...6600...6700...6800...6900...7000...7100...7200...7300...7400...7500...7600...7700...7800...7900..."
     ]
    }
   ],
   "source": [
    "movie_user_dict={}\n",
    "for movie_index in range(movie_quantity):\n",
    "    movie_user_dict[movie_index] = np.where(user_movie_rating_array[:,movie_index] >0)[0].tolist()\n",
    "    if movie_index % 100 == 0 :print(movie_index,end=\"...\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0,\n",
       " 9,\n",
       " 14,\n",
       " 15,\n",
       " 16,\n",
       " 18,\n",
       " 19,\n",
       " 21,\n",
       " 22,\n",
       " 30,\n",
       " 31,\n",
       " 36,\n",
       " 40,\n",
       " 42,\n",
       " 43,\n",
       " 44,\n",
       " 48,\n",
       " 50,\n",
       " 52,\n",
       " 53,\n",
       " 56,\n",
       " 58,\n",
       " 59,\n",
       " 61,\n",
       " 65,\n",
       " 67,\n",
       " 73,\n",
       " 74,\n",
       " 79,\n",
       " 82,\n",
       " 84,\n",
       " 89,\n",
       " 91,\n",
       " 96,\n",
       " 97,\n",
       " 99,\n",
       " 100,\n",
       " 105,\n",
       " 106,\n",
       " 108,\n",
       " 109,\n",
       " 110,\n",
       " 111,\n",
       " 113,\n",
       " 115,\n",
       " 118,\n",
       " 126,\n",
       " 127,\n",
       " 135,\n",
       " 136,\n",
       " 137,\n",
       " 139,\n",
       " 143,\n",
       " 147,\n",
       " 151,\n",
       " 161,\n",
       " 166,\n",
       " 167,\n",
       " 169,\n",
       " 170,\n",
       " 178,\n",
       " 181,\n",
       " 183,\n",
       " 184,\n",
       " 187,\n",
       " 188,\n",
       " 202,\n",
       " 205,\n",
       " 206,\n",
       " 207,\n",
       " 216,\n",
       " 217,\n",
       " 218,\n",
       " 219,\n",
       " 220,\n",
       " 224,\n",
       " 229,\n",
       " 234,\n",
       " 238,\n",
       " 245,\n",
       " 249,\n",
       " 252,\n",
       " 254,\n",
       " 257,\n",
       " 261,\n",
       " 269,\n",
       " 271,\n",
       " 272,\n",
       " 273,\n",
       " 274,\n",
       " 275,\n",
       " 278,\n",
       " 283,\n",
       " 285,\n",
       " 287,\n",
       " 288,\n",
       " 289,\n",
       " 290,\n",
       " 291,\n",
       " 293,\n",
       " 295,\n",
       " 298,\n",
       " 299,\n",
       " 302,\n",
       " 304,\n",
       " 306,\n",
       " 307,\n",
       " 308,\n",
       " 309,\n",
       " 312,\n",
       " 318,\n",
       " 321,\n",
       " 323,\n",
       " 326,\n",
       " 330,\n",
       " 332,\n",
       " 338,\n",
       " 342,\n",
       " 353,\n",
       " 356,\n",
       " 361,\n",
       " 364,\n",
       " 366,\n",
       " 367,\n",
       " 371,\n",
       " 372,\n",
       " 376,\n",
       " 378,\n",
       " 383,\n",
       " 387,\n",
       " 390,\n",
       " 391,\n",
       " 396,\n",
       " 400,\n",
       " 404,\n",
       " 408,\n",
       " 410,\n",
       " 411,\n",
       " 412,\n",
       " 414,\n",
       " 416,\n",
       " 426,\n",
       " 427,\n",
       " 432,\n",
       " 436,\n",
       " 437,\n",
       " 439,\n",
       " 441,\n",
       " 443,\n",
       " 446,\n",
       " 450,\n",
       " 452,\n",
       " 454,\n",
       " 455,\n",
       " 456,\n",
       " 457,\n",
       " 458,\n",
       " 460,\n",
       " 463,\n",
       " 466,\n",
       " 473,\n",
       " 475,\n",
       " 477,\n",
       " 479,\n",
       " 480,\n",
       " 484,\n",
       " 487,\n",
       " 488,\n",
       " 489,\n",
       " 496,\n",
       " 501,\n",
       " 503,\n",
       " 505,\n",
       " 507,\n",
       " 508,\n",
       " 510,\n",
       " 515,\n",
       " 521,\n",
       " 523,\n",
       " 524,\n",
       " 527,\n",
       " 528,\n",
       " 529,\n",
       " 530,\n",
       " 538,\n",
       " 539,\n",
       " 542,\n",
       " 543,\n",
       " 548,\n",
       " 551,\n",
       " 552,\n",
       " 555,\n",
       " 556,\n",
       " 558,\n",
       " 559,\n",
       " 563,\n",
       " 564,\n",
       " 565,\n",
       " 568,\n",
       " 571,\n",
       " 573,\n",
       " 578,\n",
       " 580,\n",
       " 581,\n",
       " 582,\n",
       " 584,\n",
       " 590,\n",
       " 593,\n",
       " 597,\n",
       " 598,\n",
       " 599,\n",
       " 607,\n",
       " 610,\n",
       " 611,\n",
       " 620,\n",
       " 621,\n",
       " 623,\n",
       " 627,\n",
       " 628,\n",
       " 633,\n",
       " 634,\n",
       " 638,\n",
       " 640,\n",
       " 643,\n",
       " 645,\n",
       " 649,\n",
       " 650,\n",
       " 651,\n",
       " 653,\n",
       " 655,\n",
       " 656,\n",
       " 657,\n",
       " 658,\n",
       " 660,\n",
       " 664,\n",
       " 668,\n",
       " 672,\n",
       " 673,\n",
       " 675,\n",
       " 676,\n",
       " 681,\n",
       " 682,\n",
       " 687,\n",
       " 691,\n",
       " 692,\n",
       " 693,\n",
       " 696,\n",
       " 697,\n",
       " 699,\n",
       " 701,\n",
       " 707,\n",
       " 712,\n",
       " 714,\n",
       " 715,\n",
       " 716,\n",
       " 722,\n",
       " 729,\n",
       " 732,\n",
       " 734,\n",
       " 737,\n",
       " 740,\n",
       " 747,\n",
       " 748,\n",
       " 750,\n",
       " 753,\n",
       " 754,\n",
       " 757,\n",
       " 759,\n",
       " 762,\n",
       " 766,\n",
       " 767,\n",
       " 771,\n",
       " 772,\n",
       " 773,\n",
       " 775,\n",
       " 777,\n",
       " 781,\n",
       " 783,\n",
       " 785,\n",
       " 786,\n",
       " 788,\n",
       " 794,\n",
       " 795,\n",
       " 797,\n",
       " 798,\n",
       " 800,\n",
       " 806,\n",
       " 807,\n",
       " 810,\n",
       " 813,\n",
       " 814,\n",
       " 817,\n",
       " 819,\n",
       " 820,\n",
       " 821,\n",
       " 825,\n",
       " 826,\n",
       " 832,\n",
       " 833,\n",
       " 834,\n",
       " 836,\n",
       " 840,\n",
       " 841,\n",
       " 842,\n",
       " 843,\n",
       " 844,\n",
       " 847,\n",
       " 848,\n",
       " 852,\n",
       " 860,\n",
       " 863,\n",
       " 864,\n",
       " 865,\n",
       " 867,\n",
       " 869,\n",
       " 870,\n",
       " 875,\n",
       " 876,\n",
       " 881,\n",
       " 886,\n",
       " 894,\n",
       " 897,\n",
       " 900,\n",
       " 903,\n",
       " 910,\n",
       " 915,\n",
       " 921,\n",
       " 925,\n",
       " 931,\n",
       " 938,\n",
       " 939,\n",
       " 950,\n",
       " 955,\n",
       " 957,\n",
       " 959,\n",
       " 961,\n",
       " 962,\n",
       " 965,\n",
       " 968,\n",
       " 969,\n",
       " 971,\n",
       " 972,\n",
       " 975,\n",
       " 976,\n",
       " 977,\n",
       " 978,\n",
       " 981,\n",
       " 983,\n",
       " 987,\n",
       " 993,\n",
       " 995,\n",
       " 996,\n",
       " 998,\n",
       " 999,\n",
       " 1004,\n",
       " 1005,\n",
       " 1008,\n",
       " 1014,\n",
       " 1015,\n",
       " 1016,\n",
       " 1021,\n",
       " 1023,\n",
       " 1025,\n",
       " 1027,\n",
       " 1029,\n",
       " 1030,\n",
       " 1032,\n",
       " 1033,\n",
       " 1034,\n",
       " 1035,\n",
       " 1038,\n",
       " 1039,\n",
       " 1046,\n",
       " 1051,\n",
       " 1057,\n",
       " 1061,\n",
       " 1062,\n",
       " 1067,\n",
       " 1074,\n",
       " 1080,\n",
       " 1083,\n",
       " 1084,\n",
       " 1088,\n",
       " 1089,\n",
       " 1090,\n",
       " 1095,\n",
       " 1099,\n",
       " 1101,\n",
       " 1103,\n",
       " 1105,\n",
       " 1106,\n",
       " 1107,\n",
       " 1108,\n",
       " 1109,\n",
       " 1110,\n",
       " 1114,\n",
       " 1115,\n",
       " 1117,\n",
       " 1118,\n",
       " 1120,\n",
       " 1121,\n",
       " 1125,\n",
       " 1126,\n",
       " 1128,\n",
       " 1129,\n",
       " 1130,\n",
       " 1131,\n",
       " 1135,\n",
       " 1144,\n",
       " 1147,\n",
       " 1148,\n",
       " 1149,\n",
       " 1155,\n",
       " 1159,\n",
       " 1160,\n",
       " 1163,\n",
       " 1166,\n",
       " 1167,\n",
       " 1168,\n",
       " 1174,\n",
       " 1176,\n",
       " 1179,\n",
       " 1181,\n",
       " 1182,\n",
       " 1183,\n",
       " 1186,\n",
       " 1189,\n",
       " 1190,\n",
       " 1192,\n",
       " 1194,\n",
       " 1197,\n",
       " 1199,\n",
       " 1202,\n",
       " 1211,\n",
       " 1216,\n",
       " 1217,\n",
       " 1218,\n",
       " 1221,\n",
       " 1225,\n",
       " 1228,\n",
       " 1229,\n",
       " 1232,\n",
       " 1233,\n",
       " 1234,\n",
       " 1239,\n",
       " 1242,\n",
       " 1243,\n",
       " 1257,\n",
       " 1259,\n",
       " 1260,\n",
       " 1263,\n",
       " 1266,\n",
       " 1268,\n",
       " 1269,\n",
       " 1270,\n",
       " 1275,\n",
       " 1276,\n",
       " 1277,\n",
       " 1281,\n",
       " 1285,\n",
       " 1286,\n",
       " 1292,\n",
       " 1295,\n",
       " 1296,\n",
       " 1300,\n",
       " 1305,\n",
       " 1308,\n",
       " 1310,\n",
       " 1311,\n",
       " 1314,\n",
       " 1316,\n",
       " 1324,\n",
       " 1325,\n",
       " 1328,\n",
       " 1330,\n",
       " 1332,\n",
       " 1333,\n",
       " 1334,\n",
       " 1336,\n",
       " 1337,\n",
       " 1340,\n",
       " 1342,\n",
       " 1343,\n",
       " 1344,\n",
       " 1347,\n",
       " 1348,\n",
       " 1349,\n",
       " 1350,\n",
       " 1359,\n",
       " 1361,\n",
       " 1362,\n",
       " 1363,\n",
       " 1364,\n",
       " 1366,\n",
       " 1376,\n",
       " 1377,\n",
       " 1378,\n",
       " 1382,\n",
       " 1383,\n",
       " 1384,\n",
       " 1385,\n",
       " 1389,\n",
       " 1392,\n",
       " 1394,\n",
       " 1398,\n",
       " 1399,\n",
       " 1400,\n",
       " 1402,\n",
       " 1403,\n",
       " 1406,\n",
       " 1411,\n",
       " 1413,\n",
       " 1415,\n",
       " 1418,\n",
       " 1420,\n",
       " 1423,\n",
       " 1427,\n",
       " 1429,\n",
       " 1432,\n",
       " 1433,\n",
       " 1438,\n",
       " 1439,\n",
       " 1442,\n",
       " 1448,\n",
       " 1449,\n",
       " 1450,\n",
       " 1452,\n",
       " 1453,\n",
       " 1456,\n",
       " 1458,\n",
       " 1460,\n",
       " 1462,\n",
       " 1463,\n",
       " 1465,\n",
       " 1471,\n",
       " 1473,\n",
       " 1474,\n",
       " 1476,\n",
       " 1478,\n",
       " 1480,\n",
       " 1483,\n",
       " 1487,\n",
       " 1492,\n",
       " 1493,\n",
       " 1495,\n",
       " 1499,\n",
       " 1502,\n",
       " 1503,\n",
       " 1504,\n",
       " 1508,\n",
       " 1511,\n",
       " 1513,\n",
       " 1515,\n",
       " 1516,\n",
       " 1518,\n",
       " 1519,\n",
       " 1520,\n",
       " 1522,\n",
       " 1525,\n",
       " 1526,\n",
       " 1527,\n",
       " 1528,\n",
       " 1532,\n",
       " 1533,\n",
       " 1534,\n",
       " 1535,\n",
       " 1541,\n",
       " 1546,\n",
       " 1547,\n",
       " 1548,\n",
       " 1549,\n",
       " 1560,\n",
       " 1561,\n",
       " 1562,\n",
       " 1563,\n",
       " 1568,\n",
       " 1570,\n",
       " 1576,\n",
       " 1580,\n",
       " 1581,\n",
       " 1583,\n",
       " 1585,\n",
       " 1587,\n",
       " 1589,\n",
       " 1590,\n",
       " 1591,\n",
       " 1592,\n",
       " 1595,\n",
       " 1596,\n",
       " 1597,\n",
       " 1599,\n",
       " 1601,\n",
       " 1603,\n",
       " 1604,\n",
       " 1605,\n",
       " 1606,\n",
       " 1608,\n",
       " 1609,\n",
       " 1610,\n",
       " 1611,\n",
       " 1612,\n",
       " 1615,\n",
       " 1616,\n",
       " 1619,\n",
       " 1627,\n",
       " 1628,\n",
       " 1630,\n",
       " 1631,\n",
       " 1632,\n",
       " 1634,\n",
       " 1635,\n",
       " 1641,\n",
       " 1643,\n",
       " 1644,\n",
       " 1649,\n",
       " 1651,\n",
       " 1658,\n",
       " 1659,\n",
       " 1661,\n",
       " 1662,\n",
       " 1663,\n",
       " 1665,\n",
       " 1670,\n",
       " 1673,\n",
       " 1675,\n",
       " 1685,\n",
       " 1689,\n",
       " 1690,\n",
       " 1691,\n",
       " 1693,\n",
       " 1695,\n",
       " 1696,\n",
       " 1698,\n",
       " 1700,\n",
       " 1704,\n",
       " 1707,\n",
       " 1710,\n",
       " 1715,\n",
       " 1716,\n",
       " 1717,\n",
       " 1718,\n",
       " 1720,\n",
       " 1722,\n",
       " 1729,\n",
       " 1731,\n",
       " 1732,\n",
       " 1734,\n",
       " 1735,\n",
       " 1737,\n",
       " 1739,\n",
       " 1749,\n",
       " 1750,\n",
       " 1751,\n",
       " 1755,\n",
       " 1757,\n",
       " 1763,\n",
       " 1766,\n",
       " 1771,\n",
       " 1778,\n",
       " 1781,\n",
       " 1783,\n",
       " 1784,\n",
       " 1788,\n",
       " 1789,\n",
       " 1791,\n",
       " 1792,\n",
       " 1798,\n",
       " 1801,\n",
       " 1802,\n",
       " 1804,\n",
       " 1805,\n",
       " 1808,\n",
       " 1812,\n",
       " 1813,\n",
       " 1815,\n",
       " 1816,\n",
       " 1821,\n",
       " 1830,\n",
       " 1834,\n",
       " 1836,\n",
       " 1842,\n",
       " 1848,\n",
       " 1854,\n",
       " 1857,\n",
       " 1858,\n",
       " 1860,\n",
       " 1871,\n",
       " 1872,\n",
       " 1874,\n",
       " 1875,\n",
       " 1877,\n",
       " 1884,\n",
       " 1886,\n",
       " 1896,\n",
       " 1899,\n",
       " 1900,\n",
       " 1904,\n",
       " 1908,\n",
       " 1911,\n",
       " 1915,\n",
       " 1916,\n",
       " 1917,\n",
       " 1920,\n",
       " 1921,\n",
       " 1922,\n",
       " 1924,\n",
       " 1926,\n",
       " 1927,\n",
       " 1928,\n",
       " 1933,\n",
       " 1935,\n",
       " 1938,\n",
       " 1939,\n",
       " 1940,\n",
       " 1944,\n",
       " 1946,\n",
       " 1951,\n",
       " 1955,\n",
       " 1956,\n",
       " 1961,\n",
       " 1963,\n",
       " 1966,\n",
       " 1968,\n",
       " 1971,\n",
       " 1977,\n",
       " 1979,\n",
       " 1981,\n",
       " 1982,\n",
       " 1984,\n",
       " 1985,\n",
       " 1986,\n",
       " 1988,\n",
       " 1989,\n",
       " 1991,\n",
       " 1992,\n",
       " 1995,\n",
       " 1996,\n",
       " 2001,\n",
       " 2002,\n",
       " 2003,\n",
       " 2008,\n",
       " 2017,\n",
       " 2021,\n",
       " 2023,\n",
       " 2024,\n",
       " 2025,\n",
       " 2026,\n",
       " 2038,\n",
       " 2039,\n",
       " 2050,\n",
       " 2055,\n",
       " 2059,\n",
       " 2062,\n",
       " 2064,\n",
       " 2067,\n",
       " 2068,\n",
       " 2071,\n",
       " 2074,\n",
       " 2075,\n",
       " 2077,\n",
       " 2078,\n",
       " 2079,\n",
       " 2080,\n",
       " 2081,\n",
       " 2084,\n",
       " 2088,\n",
       " 2093,\n",
       " 2100,\n",
       " 2102,\n",
       " 2114,\n",
       " 2119,\n",
       " 2120,\n",
       " 2122,\n",
       " 2125,\n",
       " 2129,\n",
       " 2132,\n",
       " 2141,\n",
       " 2142,\n",
       " 2143,\n",
       " 2149,\n",
       " 2150,\n",
       " 2151,\n",
       " 2155,\n",
       " 2156,\n",
       " 2157,\n",
       " 2162,\n",
       " 2165,\n",
       " 2167,\n",
       " 2171,\n",
       " 2172,\n",
       " 2173,\n",
       " 2176,\n",
       " 2185,\n",
       " 2188,\n",
       " 2190,\n",
       " 2194,\n",
       " 2202,\n",
       " 2204,\n",
       " 2205,\n",
       " 2207,\n",
       " 2217,\n",
       " 2220,\n",
       " 2224,\n",
       " 2225,\n",
       " 2227,\n",
       " 2228,\n",
       " 2230,\n",
       " 2232,\n",
       " 2233,\n",
       " 2237,\n",
       " 2239,\n",
       " 2242,\n",
       " 2244,\n",
       " 2245,\n",
       " 2246,\n",
       " 2247,\n",
       " 2249,\n",
       " 2254,\n",
       " 2255,\n",
       " 2256,\n",
       " 2257,\n",
       " 2258,\n",
       " 2264,\n",
       " 2267,\n",
       " 2270,\n",
       " 2272,\n",
       " 2273,\n",
       " 2274,\n",
       " 2277,\n",
       " 2279,\n",
       " 2280,\n",
       " 2283,\n",
       " 2285,\n",
       " 2291,\n",
       " 2292,\n",
       " 2293,\n",
       " 2294,\n",
       " 2298,\n",
       " 2303,\n",
       " 2306,\n",
       " 2308,\n",
       " 2317,\n",
       " 2319,\n",
       " 2323,\n",
       " 2325,\n",
       " 2326,\n",
       " 2333,\n",
       " 2341,\n",
       " 2344,\n",
       " 2346,\n",
       " 2348,\n",
       " 2354,\n",
       " 2355,\n",
       " 2358,\n",
       " 2361,\n",
       " 2362,\n",
       " 2363,\n",
       " 2366,\n",
       " 2369,\n",
       " 2370,\n",
       " 2372,\n",
       " 2373,\n",
       " 2374,\n",
       " 2376,\n",
       " 2381,\n",
       " 2382,\n",
       " 2385,\n",
       " 2391,\n",
       " 2392,\n",
       " 2395,\n",
       " 2400,\n",
       " 2401,\n",
       " 2402,\n",
       " 2403,\n",
       " 2404,\n",
       " 2406,\n",
       " 2407,\n",
       " 2413,\n",
       " 2415,\n",
       " 2417,\n",
       " 2419,\n",
       " 2422,\n",
       " 2423,\n",
       " 2428,\n",
       " 2429,\n",
       " 2431,\n",
       " 2435,\n",
       " 2439,\n",
       " 2442,\n",
       " 2443,\n",
       " 2445,\n",
       " 2448,\n",
       " 2455,\n",
       " 2456,\n",
       " 2458,\n",
       " 2462,\n",
       " 2466,\n",
       " 2468,\n",
       " 2470,\n",
       " 2471,\n",
       " 2474,\n",
       " 2475,\n",
       " 2484,\n",
       " 2486,\n",
       " 2487,\n",
       " 2488,\n",
       " 2491,\n",
       " 2493,\n",
       " 2496,\n",
       " 2499,\n",
       " 2505,\n",
       " 2508,\n",
       " 2510,\n",
       " 2517,\n",
       " 2520,\n",
       " 2522,\n",
       " 2523,\n",
       " 2529,\n",
       " 2533,\n",
       " 2537,\n",
       " 2540,\n",
       " 2543,\n",
       " 2544,\n",
       " 2546,\n",
       " 2549,\n",
       " 2553,\n",
       " 2559,\n",
       " 2561,\n",
       " 2564,\n",
       " 2567,\n",
       " 2568,\n",
       " 2570,\n",
       " 2571,\n",
       " 2574,\n",
       " 2576,\n",
       " 2577,\n",
       " 2578,\n",
       " 2579,\n",
       " 2585,\n",
       " 2589,\n",
       " 2590,\n",
       " 2595,\n",
       " 2600,\n",
       " 2601,\n",
       " 2603,\n",
       " 2606,\n",
       " 2607,\n",
       " 2608,\n",
       " 2610,\n",
       " 2620,\n",
       " 2621,\n",
       " 2622,\n",
       " 2627,\n",
       " 2631,\n",
       " 2634,\n",
       " 2635,\n",
       " 2636,\n",
       " 2639,\n",
       " 2642,\n",
       " 2647,\n",
       " 2648,\n",
       " 2649,\n",
       " 2650,\n",
       " 2651,\n",
       " 2652,\n",
       " 2654,\n",
       " 2658,\n",
       " 2659,\n",
       " 2661,\n",
       " 2664,\n",
       " 2666,\n",
       " 2668,\n",
       " 2674,\n",
       " 2677,\n",
       " 2678,\n",
       " 2680,\n",
       " 2684,\n",
       " 2686,\n",
       " 2688,\n",
       " 2690,\n",
       " 2691,\n",
       " 2696,\n",
       " 2698,\n",
       " 2700,\n",
       " 2701,\n",
       " 2702,\n",
       " 2709,\n",
       " 2712,\n",
       " 2715,\n",
       " 2721,\n",
       " 2722,\n",
       " 2723,\n",
       " 2727,\n",
       " 2730,\n",
       " 2732,\n",
       " 2733,\n",
       " 2734,\n",
       " 2740,\n",
       " 2741,\n",
       " 2744,\n",
       " ...]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "movie_user_dict[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\ipykernel_launcher.py:20: RuntimeWarning: invalid value encountered in double_scalars\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0...100...200...300...400...500...600...700...800...900...1000...1100...1200...1300...1400...1500...1600...1700...1800...1900...2000...2100...2200...2300...2400...2500...2600...2700...2800...2900...3000...3100...3200...3300...3400...3500...3600...3700...3800...3900...4000...4100...4200...4300...4400...4500...4600...4700...4800...4900...5000...5100...5200...5300...5400...5500...5600...5700...5800...5900...6000...6100...6200...6300...6400...6500...6600...6700...6800...6900...7000...7100...7200...7300...7400...7500...7600...7700...7800...7900..."
     ]
    }
   ],
   "source": [
    "for movie_index1 in range(movie_quantity):\n",
    "    movie_user_index1=set(movie_user_dict[movie_index1])\n",
    "    for movie_index2 in range(movie_index1+1,movie_quantity):\n",
    "        movie_user_index2=set(movie_user_dict[movie_index2])\n",
    "        ##求两者的交集\n",
    "        movie_user_union=list(\n",
    "            movie_user_index1 & movie_user_index2\n",
    "        )\n",
    "        ##如果数量太大，可以随机交集的随机数集合\n",
    "        if len(movie_user_union) > 300 :\n",
    "            movie_user_union=random.sample(movie_user_union,300)\n",
    "        #公共用户的打分向量\n",
    "        movie1_user_rating_v=user_movie_rating_array[:,movie_index1][movie_user_union]\n",
    "        movie2_user_rating_v=user_movie_rating_array[:,movie_index2][movie_user_union]\n",
    "        #时间惩罚向量\n",
    "        time_punish_v=np.around( 1 / (1 + np.abs(user_movie_time_array[:,movie_index1][movie_user_union]- user_movie_time_array[:,movie_index2][movie_user_union]) / 200000),3)\n",
    "        #用户活跃度惩罚向量\n",
    "        this_user_popular_punish_v=user_popular_punish_v[movie_user_union]\n",
    "        #求出相似度\n",
    "        sim=np.around((movie1_user_rating_v * movie2_user_rating_v * time_punish_v * this_user_popular_punish_v).sum()/np.sqrt(np.square(movie1_user_rating_v).sum() * np.square(movie2_user_rating_v).sum()),3)\n",
    "        movie_sim_array[movie_index1][movie_index2] = sim\n",
    "        movie_sim_array[movie_index2][movie_index1] = sim\n",
    "    if movie_index1 % 100 == 0 :print(movie_index1,end=\"...\")\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.   , 0.233, 0.241, ...,   nan,   nan,   nan],\n",
       "       [0.233, 0.   , 0.237, ..., 0.186, 0.202, 0.202],\n",
       "       [0.241, 0.237, 0.   , ..., 0.186, 0.202, 0.202],\n",
       "       ...,\n",
       "       [  nan, 0.186, 0.186, ..., 0.   ,   nan,   nan],\n",
       "       [  nan, 0.202, 0.202, ...,   nan, 0.   , 0.202],\n",
       "       [  nan, 0.202, 0.202, ...,   nan, 0.202, 0.   ]])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "movie_sim_array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 生成推荐"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0...100...200...300...400...500...600...700...800...900...1000...1100...1200...1300...1400...1500...1600...1700...1800...1900...2000...2100...2200...2300...2400...2500...2600...2700...2800...2900...3000...3100...3200...3300...3400...3500...3600...3700...3800...3900...4000...4100...4200...4300...4400...4500...4600...4700...4800...4900...5000...5100...5200...5300...5400...5500...5600...5700...5800...5900...6000...6100...6200...6300...6400...6500...6600...6700...6800...6900...7000...7100...7200...7300...7400...7500...7600...7700...7800...7900...8000...8100...8200...8300...8400...8500...8600...8700...8800...8900...9000...9100...9200...9300...9400...9500...9600...9700...9800...9900...10000...10100...10200...10300...10400...10500...10600...10700...10800...10900...11000...11100...11200...11300...11400...11500...11600...11700...11800...11900...12000...12100...12200...12300...12400...12500...12600...12700...12800...12900...13000...13100...13200...13300...13400...13500...13600...13700...13800...13900...14000...14100...14200...14300...14400...14500...14600...14700...14800...14900...15000...15100...15200...15300...15400...15500...15600...15700...15800...15900...16000...16100...16200...16300...16400...16500...16600...16700...16800...16900...17000...17100...17200...17300...17400...17500...17600...17700...17800...17900...18000...18100...18200...18300...18400...18500...18600...18700...18800...18900...19000...19100...19200...19300...19400...19500...19600...19700...19800...19900...20000...20100...20200...20300...20400...20500...20600...20700...20800...20900...21000...21100...21200...21300...21400...21500...21600...21700...21800...21900...22000...22100...22200...22300...22400...22500...22600...22700...22800...22900...23000...23100...23200...23300...23400...23500...23600...23700...23800...23900...24000...24100...24200...24300...24400...24500...24600...24700...24800...24900...25000...25100...25200...25300...25400...25500...25600...25700...25800...25900...26000...26100...26200...26300...26400...26500...26600...26700...26800...26900...27000...27100...27200...27300...27400...27500...27600...27700...27800...27900...28000...28100...28200...28300...28400...28500...28600...28700...28800...28900...29000...29100...29200...29300...29400...29500...29600...29700...29800...29900...30000...30100...30200...30300...30400...30500...30600...30700...30800...30900...31000...31100...31200...31300...31400...31500...31600...31700...31800...31900...32000...32100...32200...32300...32400...32500...32600...32700...32800...32900...33000...33100...33200...33300...33400...33500...33600...33700...33800...33900...34000...34100...34200...34300...34400...34500...34600...34700...34800...34900...35000...35100...35200...35300...35400...35500...35600...35700...35800...35900...36000...36100...36200...36300...36400...36500...36600...36700...36800...36900...37000...37100...37200...37300...37400...37500...37600...37700...37800...37900...38000...38100...38200...38300...38400...38500...38600...38700...38800...38900...39000...39100...39200...39300...39400...39500...39600...39700...39800...39900...40000...40100...40200...40300...40400...40500...40600...40700...40800...40900...41000...41100...41200...41300...41400...41500...41600...41700...41800...41900...42000...42100...42200...42300...42400...42500...42600...42700...42800...42900...43000...43100...43200...43300...43400...43500...43600...43700...43800...43900...44000...44100...44200...44300...44400...44500...44600...44700...44800...44900...45000...45100...45200...45300...45400...45500...45600...45700...45800...45900...46000...46100...46200...46300...46400...46500...46600...46700...46800...46900...47000...47100...47200...47300...47400...47500...47600...47700...47800...47900...48000...48100...48200...48300...48400...48500...48600...48700...48800...48900...49000...49100...49200...49300...49400...49500...49600...49700...49800...49900...50000...50100...50200...50300...50400...50500...50600...50700...50800...50900...51000...51100...51200...51300...51400...51500...51600...51700...51800...51900...52000...52100..."
     ]
    }
   ],
   "source": [
    "user_recommend ={}\n",
    "\n",
    "for user_index in range(user_quantity):\n",
    "    fav_movie_index =np.where(\n",
    "        user_movie_rating_array[user_index] >=3\n",
    "    )[0].tolist()\n",
    "    \n",
    "    df_sim_sum =pd.DataFrame(movie_sim_array[fav_movie_index].sum(axis=0),columns=[\"sim_sum\"])\n",
    "    user_recommend[user_index]=df_sim_sum.query(\n",
    "        'sim_sum > 0' \n",
    "    ).sort_values(by='sim_sum',ascending=False).index[:100].tolist()\n",
    "    \n",
    "    if user_index % 100 == 0 :print(user_index,end='...')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>movie_id</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1090</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:44:13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1136</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:30:09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>1193</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:31:30</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>1208</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:33:35</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>1219</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2004-09-10 03:13:14</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id  movie_id  rating            timestamp\n",
       "0        1      1090     4.0  2005-04-02 23:44:13\n",
       "1        1      1136     3.5  2005-04-02 23:30:09\n",
       "2        1      1193     3.5  2005-04-02 23:31:30\n",
       "3        1      1208     3.5  2005-04-02 23:33:35\n",
       "4        1      1219     4.0  2004-09-10 03:13:14"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_rating_text=pd.read_csv('./data/rating_text.csv')\n",
    "df_rating_text.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_index</th>\n",
       "      <th>movie_index</th>\n",
       "      <th>rating</th>\n",
       "      <th>timestamp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>291</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2005-04-02 23:44:13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>232</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:30:09</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>53</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:31:30</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>54</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2005-04-02 23:33:35</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>55</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2004-09-10 03:13:14</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_index  movie_index  rating            timestamp\n",
       "0           0          291     4.0  2005-04-02 23:44:13\n",
       "1           0          232     3.5  2005-04-02 23:30:09\n",
       "2           0           53     3.5  2005-04-02 23:31:30\n",
       "3           0           54     3.5  2005-04-02 23:33:35\n",
       "4           0           55     4.0  2004-09-10 03:13:14"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 将user_id,movie_id变成user_index,movie_index\n",
    "def deal_with_userid(user_id):\n",
    "    return user_id_to_index_dict[user_id] if user_id in user_id_to_index_dict.keys() else None\n",
    "def deal_with_movieid(movie_id):\n",
    "    return movie_id_to_index_dict[movie_id] if movie_id in movie_id_to_index_dict.keys() else None\n",
    "\n",
    "df_rating_text['user_id'] =df_rating_text['user_id'].apply(deal_with_userid)\n",
    "df_rating_text['movie_id'] =df_rating_text['movie_id'].apply(deal_with_movieid)\n",
    "#删除为nan的数据\n",
    "df_rating_text=df_rating_text.dropna()\n",
    "#修改列名\n",
    "df_rating_text.columns=['user_index','movie_index','rating','timestamp']\n",
    "df_rating_text['user_index'] = df_rating_text['user_index'].astype(int)\n",
    "df_rating_text['movie_index'] = df_rating_text['movie_index'].astype(int)\n",
    "df_rating_text.head()\n",
    "\n",
    "\n",
    "# df_id_to_index(df_rating_text,'user_id','user_index')\n",
    "# df_id_to_index(df_rating_text,'movie_id','movie_index')\n",
    "# df_rating_text.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0...100...200...300...400...500...600...700...800...900...1000...1100...1200...1300...1400...1500...1600...1700...1800...1900...2000...2100...2200...2300...2400...2500...2600...2700...2800...2900...3000...3100...3200...3300...3400...3500...3600...3700...3800...3900...4000...4100...4200...4300...4400...4500...4600...4700...4800...4900...5000...5100...5200...5300...5400...5500...5600...5700...5800...5900...6000...6100...6200...6300...6400...6500...6600...6700...6800...6900...7000...7100...7200...7300...7400...7500...7600...7700...7800...7900...8000...8100...8200...8300...8400...8500...8600...8700...8800...8900...9000...9100...9200...9300...9400...9500...9600...9700...9800...9900...10000...10100...10200...10300...10400...10500...10600...10700...10800...10900...11000...11100...11200...11300...11400...11500...11600...11700...11800...11900...12000...12100...12200...12300...12400...12500...12600...12700...12800...12900...13000...13100...13200...13300...13400...13500...13600...13700...13800...13900...14000...14100...14200...14300...14400...14500...14600...14700...14800...14900...15000...15100...15200...15300...15400...15500...15600...15700...15800...15900...16000...16100...16200...16300...16400...16500...16600...16700...16800...16900...17000...17100...17200...17300...17400...17500...17600...17700...17800...17900...18000...18100...18200...18300...18400...18500...18600...18700...18800...18900...19000...19100...19200...19300...19400...19500...19600...19700...19800...19900...20000...20100...20200...20300...20400...20500...20600...20700...20800...20900...21000...21100...21200...21300...21400...21500...21600...21700...21800...21900...22000...22100...22200...22300...22400...22500...22600...22700...22800...22900...23000...23100...23200...23300...23400...23500...23600...23700...23800...23900...24000...24100...24200...24300...24400...24500...24600...24700...24800...24900...25000...25100...25200...25300...25400...25500...25600...25700...25800...25900...26000...26100...26200...26300...26400...26500...26600...26700...26800...26900...27000...27100...27200...27300...27400...27500...27600...27700...27800...27900...28000...28100...28200...28300...28400...28500...28600...28700...28800...28900...29000...29100...29200...29300...29400...29500...29600...29700...29800...29900...30000...30100...30200...30300...30400...30500...30600...30700...30800...30900...31000...31100...31200...31300...31400...31500...31600...31700...31800...31900...32000...32100...32200...32300...32400...32500...32600...32700...32800...32900...33000...33100...33200...33300...33400...33500...33600...33700...33800...33900...34000...34100...34200...34300...34400...34500...34600...34700...34800...34900...35000...35100...35200...35300...35400...35500...35600...35700...35800...35900...36000...36100...36200...36300...36400...36500...36600...36700...36800...36900...37000...37100...37200...37300...37400...37500...37600...37700...37800...37900...38000...38100...38200...38300...38400...38500...38600...38700...38800...38900...39000...39100...39200...39300...39400...39500...39600...39700...39800...39900...40000...40100...40200...40300...40400...40500...40600...40700...40800...40900...41000...41100...41200...41300...41400...41500...41600...41700...41800...41900...42000...42100...42200...42300...42400...42500...42600...42700...42800...42900...43000...43100...43200...43300...43400...43500...43600...43700...43800...43900...44000...44100...44200...44300...44400...44500...44600...44700...44800...44900...45000...45100...45200...45300...45400...45500...45600...45700...45800...45900...46000...46100...46200...46300...46400...46500...46600...46700...46800...46900...47000...47100...47200...47300...47400...47500...47600...47700...47800...47900...48000...48100...48200...48300...48400...48500...48600...48700...48800...48900...49000...49100...49200...49300...49400...49500...49600...49700...49800...49900...50000...50100...50200...50300...50400...50500...50600...50700...50800...50900...51000...51100...51200...51300...51400...51500...51600...51700...51800...51900...52000...52100..."
     ]
    }
   ],
   "source": [
    "## 生成真实用户的推荐列表\n",
    "user_fav={}\n",
    "for user_index,groupby_userindex in df_rating_text.groupby('user_index'):\n",
    "    movies_rating=groupby_userindex.groupby('movie_index')['rating'].mean()\n",
    "    user_fav[user_index] =movies_rating[\n",
    "        movies_rating >= 3\n",
    "    ].index.tolist()\n",
    "    if user_index % 100 == 0 :print(user_index,end='...')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 计算准确率和召回率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "precision 0.09714286590987066\n",
      "recall 0.4319507654734099\n"
     ]
    }
   ],
   "source": [
    "union_quantity=0\n",
    "recommend_quantity = 0\n",
    "fav_quantity = 0\n",
    "\n",
    "for user_index in user_recommend.keys():\n",
    "        if user_index in user_fav.keys():\n",
    "            union_quantity +=len(\n",
    "                set(user_recommend[user_index]) & set(user_fav[user_index])\n",
    "            )\n",
    "            \n",
    "            recommend_quantity+=len(user_recommend[user_index])\n",
    "            fav_quantity += len(user_fav[user_index])\n",
    "            \n",
    "print(\"precision\",union_quantity / recommend_quantity)\n",
    "print('recall',union_quantity / fav_quantity)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
